package com.cloudlead.common.lang;

import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.MessageFormat;
import java.util.*;

/**
 * Created by dean on 2015/8/6.
 * <p>
 * 国际化支持。默认资源文件放在类根路径下的i18n目录下，资源文件命名为messages
 */
public final class Messages {
    private static ResourceBundle resourceBundle;

    private static final String PROPERTIES_PATH = "i18n/";

    private static final String PROPERTIES_FILE_NAME = "messages";

    static {
        try {
            AggregateBundle aggregateBundle = new AggregateBundle();
            Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources(PROPERTIES_PATH);
            while (resources.hasMoreElements()) {
                URL url = resources.nextElement();
                URLClassLoader classLoader = new URLClassLoader(new URL[]{url});
                ResourceBundle resourceBundle = ResourceBundle.getBundle(PROPERTIES_FILE_NAME, Locale.getDefault(), classLoader);
                aggregateBundle.addBundle(resourceBundle);
            }
            resourceBundle = aggregateBundle;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String getMessage(String key, Object... args) {
        String string = resourceBundle.getString(key);
        return MessageFormat.format(string, args);
    }


    /**
     * A {@link ResourceBundle} whose content is aggregated from multiple source bundles.
     * <p>
     * This class is package-private for the sake of testability.
     */
    public static class AggregateBundle extends ResourceBundle {
        private Map<String, Object> contents = new HashMap<String, Object>();

        /**
         * Creates a new AggregateBundle.
         */
        public AggregateBundle() {
        }

        @Override
        public Enumeration<String> getKeys() {
            return new IteratorEnumeration<String>(contents.keySet().iterator());
        }

        @Override
        protected Object handleGetObject(String key) {
            return contents.get(key);
        }

        public void addBundle(ResourceBundle bundle) {
            Enumeration<String> keys = bundle.getKeys();
            while (keys.hasMoreElements()) {
                String oneKey = keys.nextElement();
                contents.put(oneKey, bundle.getObject(oneKey));
            }
        }
    }

    private static class IteratorEnumeration<T> implements Enumeration<T> {

        private Iterator<T> source;

        /**
         * Creates a new IterationEnumeration.
         *
         * @param source The source iterator. Must not be null.
         */
        public IteratorEnumeration(Iterator<T> source) {

            if (source == null) {
                throw new IllegalArgumentException("Source must not be null");
            }

            this.source = source;
        }

        public boolean hasMoreElements() {
            return source.hasNext();
        }

        public T nextElement() {
            return source.next();
        }
    }
}
